﻿using Microsoft.Extensions.Configuration;
using NP.BPMReportPlatform.Common;
using NP.BPMReportPlatform.Contract.Dtos;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.ElectronicSign;
using NP.BPMReportPlatform.EmpCertification.Dto;
using NP.BPMReportPlatform.Entities.BPM_Business;
using NP.BPMReportPlatform.Entities.BPM_Platform;
using NP.BPMReportPlatform.WordHelper;
using NP.Enterprise.Utils.Http;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;

namespace NP.BPMReportPlatform.EmpCertification
{
    /// <summary>
    /// 员工证明接口
    /// </summary>
    public class EmpCertificationService : BPMReportPlatformAppService, IEmpCertificationService
    {
        #region Variables

        private readonly SqlSugarClient _db;
        private readonly SqlSugarClient _dbPlatform;
        private readonly INPRestHttpHelper _nPRestHttp;
        private readonly string _esbSAPUrl;
        private readonly ICommonService _commonService;

        #endregion

        #region Constructor

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="sqlSugarAppService"></param>
        public EmpCertificationService(ISqlSugarAppService sqlSugarAppService,
            INPRestHttpHelper nPRestHttp, IConfiguration configuration, ICommonService commonService)
        {
            _db = sqlSugarAppService.GetBusinessInstance();
            _dbPlatform = sqlSugarAppService.GetPlatformInstance();
            _nPRestHttp = nPRestHttp;
            _esbSAPUrl = configuration["Nippon:ESB:SYQ_ESB_ERPHR_API"];
            _commonService = commonService;
        }

        #endregion


        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<GetEmpCertResultOutput>> GetAllResult(GetEmpCertResultInput input)
        {
            RefAsync<int> totalCount = 0;

            // 权限过滤
            var currentWorkNumber = CurrentUser != null && CurrentUser.UserName != null ? CurrentUser.UserName : string.Empty;
            var role = getUserRoles(input);
            var listQueryable = await _db.Queryable<EmpCertificationEntity, BusinessProcessesNew>((t, b) => t.InstanceNumber == b.InstanceId)
            .WhereIF(!input.WorkNumber.IsNullOrEmpty(), (t, b) => t.WorkNumber.Contains(input.WorkNumber))
            .WhereIF(!input.UserName.IsNullOrEmpty(), (t, b) => t.UserName.Contains(input.UserName))
            .WhereIF(!input.InstanceNumber.IsNullOrEmpty(), (t, b) => t.InstanceNumber.Contains(input.InstanceNumber))
            .WhereIF(!input.SealType.IsNullOrEmpty(), (t, b) => t.SealType.Contains(input.SealType))
            .WhereIF(!role.Item1 && !input.IsAdmin, (t, b) => SqlFunc.ContainsArray(role.Item2, t.WorkNumber) || t.WorkNumber == currentWorkNumber)
            .Select((t, b) =>
                new GetEmpCertResultOutput()
                {
                    Id = t.Id,
                    UserName = t.UserName,
                    WorkNumber = t.WorkNumber,
                    InstanceNumber = t.InstanceNumber,
                    UserArea = t.UserArea,
                    ContractAddress = t.ContractAddress,
                    ErName = t.ErName,
                    ErEmail = t.ErEmail,
                    XzName = t.XzName,
                    XzEmail = t.XzEmail,
                    CertTypeCode = t.CertTypeCode,
                    CertTypeName = t.CertTypeName,
                    UseReason = t.UseReason,
                    CertTemplate = t.CertTemplate,
                    SealType = t.SealType,
                    CertGetFun = t.CertGetFun,
                    MailUserName = t.MailUserName,
                    MailPhone = t.MailPhone,
                    MailAddress = t.MailAddress,
                    Remark = t.Remark,
                    FileKey = t.FileKey,
                    SignFlowId = t.SignFlowId,
                    SignErrorMsg = t.SignErrorMsg,
                    StatusName = t.StatusName,
                    Mobile = t.Mobile,
                    AddTime = b.StartTime,
                    FinishTime = b.FinishTime,
                    RiskCode = t.RiskCode,
                    RiskPushErrorMsg = t.RiskPushErrorMsg,
                    RiskPushStatus = t.RiskPushStatus
                }).OrderBy(t => t.InstanceNumber, OrderByType.Desc)
                .ToPageListAsync(input.PageIndex, input.PageSize, totalCount);

            // 如果是本人，risk码不给看
            listQueryable.ForEach(t =>
            {
                if (!role.Item1 && !SqlFunc.ContainsArray(role.Item2, t.WorkNumber))
                {
                    t.RiskCode = string.Empty;
                    t.RiskPushErrorMsg = string.Empty;
                }
            });

            //返回结果
            return new PagedResultDto<GetEmpCertResultOutput>()
            {
                TotalCount = totalCount,
                Items = listQueryable
            };
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="instanceNumber">流程号</param>
        /// <returns></returns>
        public async Task<byte[]> DownloadEmpCertificationUnEsign(string instanceNumber)
        {
            var entity = await _db.Queryable<EmpCertificationEntity>().Where(t => t.InstanceNumber == instanceNumber).FirstAsync();
            var userExtension = _dbPlatform.Queryable<UserExtension>().First(t => t.Sapemployeeid == entity.WorkNumber);
            var corporateA = _dbPlatform.Queryable<CorporateEntity>().First(t => t.CorporateCode == userExtension.Sapcompanycode);

            var template = WordTemplateEnum.EmpCertification_1_Word;
            if (entity.CertTypeCode == "1") template = WordTemplateEnum.EmpCertification_1_Word;
            if (entity.CertTypeCode == "3") template = WordTemplateEnum.EmpCertification_3_Word;
            else if (entity.CertTypeCode == "6") template = WordTemplateEnum.EmpCertification_6_Word;

            return StreamToBytes(MiniWordHelper.CreateWord(template, PackageValues(entity, corporateA)));
        }

        /// <summary>
        /// 获取用户权限
        /// </summary>
        /// <returns></returns>
        private Tuple<bool, List<string>> getUserRoles(GetEmpCertResultInput input)
        {
            // 权限过滤
            // 管理员直接跳出
            if (input.IsAdmin)
            {
                return new Tuple<bool, List<string>>(true, new List<string>());
            }

            var currentWorkNumber = CurrentUser != null && CurrentUser.UserName != null ? CurrentUser.UserName : string.Empty;
            var userCodes = _commonService.GetUserByRoleFilter(currentWorkNumber, RelationshipTypeEnum.ER);
            userCodes = userCodes != null && userCodes.Count > 0 ? userCodes : new List<string>() { "-1" };
            bool isAdmin = userCodes.Contains("9999999999");
            if (isAdmin)
            {
                return new Tuple<bool, List<string>>(isAdmin, userCodes);
            }
            else
            {
                var userCodes1 = _commonService.GetUserByRoleFilter(currentWorkNumber, RelationshipTypeEnum.薪资员);
                if (userCodes1 != null && userCodes1.Count() > 0)
                {
                    userCodes.AddRange(userCodes1);
                    userCodes = userCodes.Distinct().ToList();
                }
            }
            return new Tuple<bool, List<string>>(isAdmin, userCodes);
        }

        /// <summary>
        /// 拼接员工证明内容
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        private Dictionary<string, object> PackageValues(EmpCertificationEntity entity, CorporateEntity corporate)
        {
            var user = _dbPlatform.Queryable<Users>().Where(p => p.WorkNumber == entity.WorkNumber).First();
            var userExtension = _dbPlatform.Queryable<UserExtension>().Where(p => p.Sapemployeeid == entity.WorkNumber).First();
            var userExtensionSecond = _dbPlatform.Queryable<UserExtensionSecondEntity>().Where(p => p.WorkNumber == entity.WorkNumber).First();

            var erMobile = _dbPlatform.Queryable<UserExtension>().Where(p => p.Name == entity.ErName && p.Email == entity.ErEmail).First();

            DateTime contractbegin = DateTime.Parse(userExtension.Contractbegin);

            Dictionary<string, object> values = new Dictionary<string, object>() {
                { "UserName", user.UserName },
                { "UserSex", user.Gender=="M"?"男":"女" },
                { "CardTypeName", userExtensionSecond.CardTypeName },
                { "CardNum", userExtensionSecond.CardNum },
                { "Year", contractbegin.Year },
                { "Month", contractbegin.Month },
                { "Day", contractbegin.Day },
                { "DepartName", user?.FullPathText },
                { "PositionName", userExtension.Employeepostname },
                { "CorporateName", corporate.CorporateName },
                { "ERName", entity.ErName },
                { "ERPhone", erMobile?.Mobile },
                { "ORT01",  userExtensionSecond?.ORT01},
                { "NOW",  DateTime.Now.ToString("yyyy年MM月dd日")}
            };
            return values;
        }

        private byte[] StreamToBytes(MemoryStream stream)
        {
            byte[] bytes = new byte[stream.Length];
            stream.Read(bytes, 0, bytes.Length);
            // 设置当前流的位置为流的开始
            stream.Seek(0, SeekOrigin.Begin);
            return bytes;
        }
    }
}